package cn.dwy2002.binaryhandwritingserver.service.impl;

import cn.dwy2002.binaryhandwritingserver.common.Result;
import cn.dwy2002.binaryhandwritingserver.common.utils.RandomIdGenerator;
import cn.dwy2002.binaryhandwritingserver.exception.ArticleNotFoundException;
import cn.dwy2002.binaryhandwritingserver.exception.EmptyIdException;
import cn.dwy2002.binaryhandwritingserver.mapper.ArticlesMapper;
import cn.dwy2002.binaryhandwritingserver.pojo.dto.ArticleDTO;
import cn.dwy2002.binaryhandwritingserver.pojo.po.Article;
import cn.dwy2002.binaryhandwritingserver.pojo.vo.ArticleVO;
import cn.dwy2002.binaryhandwritingserver.service.service.ArticleService;
import cn.hutool.core.bean.BeanUtil;
import io.micrometer.common.util.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

import static cn.dwy2002.binaryhandwritingserver.common.Result.*;

/**
 * 文章管理
 *
 * @author 杜伟毅
 * @version 1.0
 * @since 2025/05/31
 */
@Service
@RequiredArgsConstructor
public class ArticleServiceImpl implements ArticleService {
    private final ArticlesMapper mapper;

    /**
     * 获取所有文章（未被逻辑删除的）
     *
     * @return 返回所有未被删除的文章列表
     * @since 2025/5/28 0028 22:04
     */
    @Override
    public Result<List<ArticleVO>> getAllArticles() {
        return success200("获取成功", BeanUtil.copyToList(mapper.selectAll(), ArticleVO.class));
    }

    /**
     * 根据ID获取文章详情
     *
     * @param id 文章ID
     * @return 返回对应ID的文章对象，若不存在则返回null
     * @throws ArticleNotFoundException 当文章不存在时抛出异常
     * @since 2025/5/28 0028 22:04
     */
    @Override
    public Result<ArticleVO> getArticleById(Long id) throws ArticleNotFoundException {
        if (Objects.isNull(id)) throw new EmptyIdException("getArticleById");
        return success200("获取成功", BeanUtil.copyProperties(mapper.selectById(id), ArticleVO.class));
    }

    /**
     * 创建新文章
     *
     * @param dto 要创建的文章对象
     * @return 返回创建成功的文章对象（包含生成的ID等信息）
     * @since 2025/5/28 0028 22:04
     */
    @Override
    public Result<Void> createArticle(ArticleDTO dto) {
        if (Objects.isNull(dto)) {
            return fail400("文章内容不能为空");
        }
        // 2. 必填字段校验
        if (StringUtils.isBlank(dto.getTitle())) {
            return fail400("文章标题不能为空");
        }
        if (StringUtils.isBlank(dto.getContent())) {
            return fail400("文章内容不能为空");
        }

        Article article = BeanUtil.copyProperties(dto, Article.class);
        article.setId(RandomIdGenerator.generateId());
        mapper.insert(article);
        return success201("文章创建成功");
    }

    /**
     * 更新文章信息
     *
     * @param dto 要修改的文章对象
     * @return 返回更新后的文章对象
     * @throws ArticleNotFoundException 当文章不存在时抛出异常
     * @since 2025/5/28 0028 22:04
     */
    @Override
    public Result<Void> updateArticle(ArticleDTO dto) throws ArticleNotFoundException {
        // 1. 检查DTO是否有效
        if (dto == null || dto.getId() == null) {
            return Result.fail400("文章ID不能为空");
        }

        // 2. 查询文章是否存在
        Article existingArticle = mapper.selectById(dto.getId());
        if (existingArticle == null) {
            throw new ArticleNotFoundException("文章不存在");
        }

        // 3. 更新文章信息
        Article article = new Article();
        article.setId(dto.getId());
        article.setTitle(dto.getTitle());
        article.setContent(dto.getContent());

        mapper.update(article);

        return Result.success201("更新成功");
    }

    /**
     * 根据ID删除文章（逻辑删除）
     *
     * @param id 要删除的文章ID
     * @throws ArticleNotFoundException 当文章不存在时抛出异常
     * @since 2025/5/28 0028 22:04
     */
    @Override
    public Result<Void> deleteArticle(Long id) throws ArticleNotFoundException {
        // 1. 检查ID是否有效
        if (id == null) {
            return Result.fail400("文章ID不能为空");
        }

        // 2. 查询文章是否存在
        Article existingArticle = mapper.selectById(id);
        if (existingArticle == null) {
            throw new ArticleNotFoundException("文章不存在");
        }

        // 3. 执行逻辑删除
        mapper.deleteById(id);

        return Result.success201("删除成功");
    }
}
